{
  "cells": [
    {
      "attachments": {},
      "cell_type": "markdown",
      "metadata": {
        "id": "w5_pa5kKPzAE"
      },
      "source": [
        "# Memory Cookbook"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zgqKzSB-PXzi"
      },
      "source": [
        "You can also check this cookbook in colab [here](https://colab.research.google.com/drive/1ixGItEqQGkp09_TuV_8SGmz65WHBr5r5?usp=sharing)\n",
        "\n",
        "⭐ <i>Star us on [*Github*](https://github.com/camel-ai/camel), join our [*Discord*](https://discord.camel-ai.org) or follow our [*X*](https://x.com/camelaiorg)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lSXa_rQQQzBd"
      },
      "source": [
        "## Overview"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OnmoAw2vQG8I"
      },
      "source": [
        "The Memory module in CAMEL provides a flexible and powerful system for storing, retrieving, and managing information for AI agents. It enables agents to maintain context across conversations and retrieve relevant information from past interactions, enhancing the coherence and relevance of AI responses."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l4MP9uUNQ2kr"
      },
      "source": [
        "## Getting Started\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kETDiaP2Rrdb"
      },
      "source": [
        "### Installation"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Cg96MkbcRtQR"
      },
      "source": [
        "Ensure you have CAMEL AI installed in your Python environment:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": true,
        "id": "ZVmDAK6MPefC"
      },
      "outputs": [],
      "source": [
        "!pip install \"camel-ai[all]==0.2.16\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MyTTCe3IR_Lr"
      },
      "source": [
        "### 🔑 Setting Up API Keys"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "REqzgGL9SEaD"
      },
      "source": [
        "You'll need to set up your API keys for OpenAI."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PNBFEXc-R-0s",
        "outputId": "50989fca-73bf-4062-cc1f-124bd6abadc1"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Enter your API key: ··········\n"
          ]
        }
      ],
      "source": [
        "import os\n",
        "from getpass import getpass\n",
        "\n",
        "# Prompt for the API key securely\n",
        "openai_api_key = getpass('Enter your API key: ')\n",
        "os.environ[\"OPENAI_API_KEY\"] = openai_api_key"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Alternatively, if running on Colab, you could save your API keys and tokens as **Colab Secrets**, and use them across notebooks.\n",
        "\n",
        "To do so, **comment out** the above **manual** API key prompt code block(s), and **uncomment** the following codeblock.\n",
        "\n",
        "⚠️ Don't forget granting access to the API key you would be using to the current notebook."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# import os\n",
        "# from google.colab import userdata\n",
        "\n",
        "# os.environ[\"OPENAI_API_KEY\"] = userdata.get(\"OPENAI_API_KEY\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LRojeqp7dP1m"
      },
      "source": [
        "## Usage"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_sJV9GFldTBh"
      },
      "source": [
        "To use the Memory module in your agent:\n",
        "\n",
        "1. Choose an appropriate AgentMemory implementation (`ChatHistoryMemory`, `VectorDBMemory`, or `LongtermAgentMemory`).\n",
        "2. Initialize the memory with a context creator and any necessary parameters.\n",
        "3. Use `write_records()` to add new information to the memory.\n",
        "4. Use `retrieve()` to get relevant context for the agent's next action.\n",
        "5. Use `get_context()` to obtain the formatted context for the agent."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "aiypnpqJoZ4G"
      },
      "source": [
        "### Setting `LongtermAgentMemory`:"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "C2kVCRA7dD4A"
      },
      "source": [
        "Import required modules"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "UOKw2hCSdCXm"
      },
      "outputs": [],
      "source": [
        "from camel.memories import (\n",
        "    ChatHistoryBlock,\n",
        "    LongtermAgentMemory,\n",
        "    MemoryRecord,\n",
        "    ScoreBasedContextCreator,\n",
        "    VectorDBBlock,\n",
        ")\n",
        "from camel.messages import BaseMessage\n",
        "from camel.types import ModelType, OpenAIBackendRole\n",
        "from camel.utils import OpenAITokenCounter"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "pAdDeN7DdUgr",
        "outputId": "75a8c69d-8e2b-4af5-e7a7-c4205718ee10"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[{'role': 'user', 'content': 'What is CAMEL AI?'}, {'role': 'assistant', 'content': 'CAMEL-AI.org is the 1st LLM multi-agent framework and an open-source community dedicated to finding the scaling law of agents.'}]\n"
          ]
        }
      ],
      "source": [
        "# Initialize the memory\n",
        "memory = LongtermAgentMemory(\n",
        "    context_creator=ScoreBasedContextCreator(\n",
        "        token_counter=OpenAITokenCounter(ModelType.GPT_4O_MINI),\n",
        "        token_limit=1024,\n",
        "    ),\n",
        "    chat_history_block=ChatHistoryBlock(),\n",
        "    vector_db_block=VectorDBBlock(),\n",
        ")\n",
        "\n",
        "# Create and write new records\n",
        "records = [\n",
        "    MemoryRecord(\n",
        "        message=BaseMessage.make_user_message(\n",
        "            role_name=\"User\",\n",
        "            content=\"What is CAMEL AI?\",\n",
        "        ),\n",
        "        role_at_backend=OpenAIBackendRole.USER,\n",
        "    ),\n",
        "    MemoryRecord(\n",
        "        message=BaseMessage.make_assistant_message(\n",
        "            role_name=\"Agent\",\n",
        "            content=\"CAMEL-AI.org is the 1st LLM multi-agent framework and \"\n",
        "            \"an open-source community dedicated to finding the scaling law \"\n",
        "            \"of agents.\",\n",
        "        ),\n",
        "        role_at_backend=OpenAIBackendRole.ASSISTANT,\n",
        "    ),\n",
        "]\n",
        "memory.write_records(records)\n",
        "\n",
        "# Get context for the agent\n",
        "context, token_count = memory.get_context()\n",
        "\n",
        "print(context)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "pEiFYV-yez5j",
        "outputId": "c72b113f-5f75-4a7e-8f23-379c954da66e"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "49\n"
          ]
        }
      ],
      "source": [
        "print(token_count)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "K-P9rD6Foe5j"
      },
      "source": [
        "### Adding `LongtermAgentMemory` to your `ChatAgent`:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Mp-KXFdGpKZt",
        "outputId": "08ca25ef-2d14-4554-bcce-f031ef3dd740"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "CAMEL AI is recognized as the first LLM (Large Language Model) multi-agent framework. It is an open-source community initiative aimed at exploring and understanding the scaling laws of agents. The framework facilitates the development and deployment of multiple agents that can interact and collaborate, leveraging the capabilities of LLMs to enhance their performance and functionality.\n"
          ]
        }
      ],
      "source": [
        "from camel.agents import ChatAgent\n",
        "\n",
        "# Define system message for the agent\n",
        "sys_msg = \"You are a curious agent wondering about the universe.\"\n",
        "\n",
        "# Initialize agent\n",
        "agent = ChatAgent(system_message=sys_msg)\n",
        "\n",
        "# Set memory to the agent\n",
        "agent.memory = memory\n",
        "\n",
        "\n",
        "# Define a user message\n",
        "usr_msg = \"Tell me which is the 1st LLM multi-agent framework based on what we have discussed\"\n",
        "\n",
        "# Sending the message to the agent\n",
        "response = agent.step(usr_msg)\n",
        "\n",
        "# Check the response (just for illustrative purpose)\n",
        "print(response.msgs[0].content)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "w0ndTJske1mb"
      },
      "source": [
        "## Advanced Topics"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9q8EXq2ge6Dq"
      },
      "source": [
        "### Customizing Context Creator"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zUjztraTe7aw"
      },
      "source": [
        "You can create custom context creators by subclassing `BaseContextCreator`:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "id": "LX4fyovCe89R"
      },
      "outputs": [],
      "source": [
        "from camel.memories import BaseContextCreator\n",
        "\n",
        "class MyCustomContextCreator(BaseContextCreator):\n",
        "    @property\n",
        "    def token_counter(self):\n",
        "        # Implement your token counting logic\n",
        "        return\n",
        "\n",
        "    @property\n",
        "    def token_limit(self):\n",
        "        return 1000  # Or any other limit\n",
        "\n",
        "    def create_context(self, records):\n",
        "        # Implement your context creation logic\n",
        "        pass"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "N_HM5wyFfEtO"
      },
      "source": [
        "### Customizing Vector Database Block"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CxcjHzArfFYZ"
      },
      "source": [
        "For `VectorDBBlock`, you can customize it by adjusting the embedding models or vector storages:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "iQlxwVM7fJEp"
      },
      "outputs": [],
      "source": [
        "from camel.embeddings import OpenAIEmbedding\n",
        "from camel.memories import VectorDBBlock\n",
        "from camel.storages import QdrantStorage\n",
        "\n",
        "vector_db = VectorDBBlock(\n",
        "    embedding=OpenAIEmbedding(),\n",
        "    storage=QdrantStorage(vector_dim=OpenAIEmbedding().get_output_dim()),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u_pkVP5Eg2vv"
      },
      "source": [
        "### Performance Considerations"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_4C93qAng3SP"
      },
      "source": [
        "- For large-scale applications, consider using persistent storage backends instead of in-memory storage.\n",
        "- Optimize your context creator to balance between context relevance and token limits.\n",
        "- When using `VectorDBMemory`, be mindful of the trade-off between retrieval accuracy and speed as the database grows."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
